package com.weipt.rabbitmq;

import com.rabbitmq.client.*;

import java.io.IOException;
import java.util.concurrent.TimeoutException;

/**
 * 发布订阅模式
 * 没有路由key，会将消息发给所有绑定的queue
 * 比如一个交换机绑定了3个队列，那么发送一条消息之后，3个对列都能收到消息
 */
public class HelloFanout {

    public static final String QUEUE_NAME1 = "hello-fanout-queue1";

    public static final String QUEUE_NAME2 = "hello-fanout-queue2";

    public static final String QUEUE_NAME3 = "hello-fanout-queue3";
    public static final String EXCHANGE_NAME = "hello-fanout-exchange";
    public static final String EXCHANGE_TYPE = "fanout";

    public static void main(String[] args) throws IOException, TimeoutException {
        publish("test fanout");
        consume();
    }

    public static void publish(String msg) throws IOException, TimeoutException {
        Connection mqConn = ConnectionUtils.getMqConn();
        Channel channel = mqConn.createChannel(); //创建一个新的管道
        channel.exchangeDeclare(EXCHANGE_NAME, EXCHANGE_TYPE);    //创建一个新的交换机exchange，一般项目中exchange都会提前规划好，此处仅演示
        //通道绑定对应消息队列
        channel.queueDeclare(QUEUE_NAME1, false, false, false, null);
        channel.queueDeclare(QUEUE_NAME2, false, false, false, null);
        channel.queueDeclare(QUEUE_NAME3, false, false, false, null);
        channel.queueBind(QUEUE_NAME1, EXCHANGE_NAME, "");
        channel.queueBind(QUEUE_NAME2, EXCHANGE_NAME, "");
        channel.queueBind(QUEUE_NAME3, EXCHANGE_NAME, "");
        //channel.queueBind(QUEUE_NAME1, EXCHANGE_NAME, "");//绑定之后，如果修改了routingkey，相当于增加绑定关系，而不是覆盖
        //因为rabbitmq是长连接，相当于一个连接中可以创建多个管道就行通讯，类比http长连接
        //所有的消息不能直接由channel发给queue，必须要经过exchange，如果不指定，则走默认的exchage，默认的是fanout模式。非fanout模式无法走默认
        channel.basicPublish(EXCHANGE_NAME, "",  MessageProperties.PERSISTENT_TEXT_PLAIN, msg.getBytes());
        //关闭连接
        channel.close();
        mqConn.close();
    }

    public static void consume() throws IOException {
        Connection mqConn = ConnectionUtils.getMqConn();
        Channel channel = mqConn.createChannel();
        channel.basicConsume(QUEUE_NAME1, true, new DefaultConsumer(channel) {
            @Override
            public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
                System.out.println("handleDelivery:"+consumerTag);
                System.out.println("可以通过重写handleDelivery方法，获取queue中的消息。消息内容："+new String(body));
            }
        });
        //消费端连接与同道不用关闭，一直处于监听状态
        //channel.close();
        //mqConn.close();
    }
}
